package cn.com.lms.filter;

import cn.com.lms.business.core.util.CurrentUserInstance;
import cn.com.lms.business.user.persistence.entity.SysUserVo;
import cn.com.lms.business.user.service.SysUserVoService;
import com.bnzj.cloud.business.core.persistence.entity.SysResource;
import com.bnzj.cloud.business.core.service.SysResourceService;
import com.bnzj.core.rest.ResponseResult;
import com.bnzj.core.rest.ResultCode;
import com.bnzj.core.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;

/**
 * @ClassName CurrentUserFilter
 * @Description 获取用户信息Filter
 * @Author Joy.zhou
 * @Date 2020/5/19
 * @Version V1.0
 **/
@Slf4j
@Component
@WebFilter(urlPatterns = "/*")
public class CurrentUserFilter implements Filter {

    @Autowired
    private SysUserVoService sysUserVoService;

    @Autowired
    private SysResourceService sysResourceService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String userName = ((HttpServletRequest)request).getHeader("X-USER-NAME");
        String phoneNum = ((HttpServletRequest)request).getHeader("X-PHONE-NUM");
        SysUserVo sysUser = null;
        if (userName != null) {
            sysUser = sysUserVoService.findByAccount(userName);
        }
        else if(phoneNum != null) {
            sysUser = sysUserVoService.findByPhone(phoneNum);
        }
        if(sysUser == null){
            log.warn(MessageFormat.format("用户{0}不存在!", userName));
        }
        if(sysUser != null && doCheck((HttpServletRequest) request, userName)){
            CurrentUserInstance.setCurrentUser(sysUser);
            chain.doFilter(request, response);
        }else {
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            ResultCode code = ResultCode.getResultCode(ResultCode.ACCESS_DENIED);
            ResponseResult result = new ResponseResult(code);
            response.getWriter().write(JsonUtils.objToJson(result));
            return;
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    private boolean doCheck(HttpServletRequest request, String userName) {
        boolean result = true;
        AntPathMatcher apm = new AntPathMatcher();
        String uri = request.getRequestURI();
        List<SysResource> allResource = sysResourceService.findAll();
        boolean isResourceSecured = allResource.stream()
                .anyMatch(resource -> resource.getUrl() != null && apm.match(resource.getUrl(), uri));
        if (isResourceSecured) {
            List<SysResource> userResources = sysResourceService.findAllByUserAccount(userName);
            result = userResources.stream()
                    .anyMatch(resource -> apm.match(resource.getUrl(), uri));
        }
        return result;
    }
}
